#include "enemy.h"
#include "enemys/normalenemy.h"
#include "enemys/npc1.h"
#include "enemys/npc2.h"
#include "enemys/npc3.h"
#include "enemys/npc4.h"
#include "enemys/npc5.h"
#include "enemys/npc6.h"
#include "player.h"

namespace fireplane
{
	Enemy* Enemy::_createEnemy(CreateArg* arg){
		Enemy* enemy = NULL;

		switch(arg->_id){
		case ET_npc1:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC1(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;

		case ET_npc2:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC2(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;
		case ET_npc3:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC3(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;
		case ET_npc4:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC4(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;

		case ET_npc5:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC5(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;	

		case ET_npc6:
			{
				CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;
				enemy = new NPC6(targ->_id);
				enemy->onInit(arg);
				enemy->autorelease();

				_all_enemy_parent->addChild(enemy);
			}
			break;
		}
                 
		if (enemy){
			enemy->retain();
			_all_active_enemys.push_back(enemy);
		}

		return enemy;
	}

	void Enemy::updateAllEnemys( float dt )
	{
		processCreateCmds();
		list<Enemy*>::iterator it = _all_active_enemys.begin();
		for (;it != _all_active_enemys.end();){
			Enemy* enemy = *it;
			if(!enemy->updateState(dt)){
				enemy->destroy();
				it = _all_active_enemys.erase(it);
			}
			else{
				it ++;
			}
		}
	}

	void Enemy::initEnemyanager( CCNode* parent){
		_all_enemy_parent = parent;
	}

	void Enemy::destroyEnemyManager()
	{
		_all_enemy_parent = NULL;
	}

	Enemy::Enemy(EnemyType type):
		_type(type),_hp(0){}

	Enemy::~Enemy(){}

	void Enemy::destroy()
	{
		removeFromParentAndCleanup(true);
	}

	list<CCRect>& Enemy::getCollisionRect()
	{
		return _all_collision_rects;
	}

	bool Enemy::isCollision2Player( Player* player )
	{
		CCRect player_rect = player->getPlayerWorldCollisionSize();

		CCAffineTransform tan = this->worldToNodeTransform();
		player_rect.size = CCSizeApplyAffineTransform(player_rect.size,tan);
		player_rect.origin = this->getParent()->convertToNodeSpace(player_rect.origin);

		
		for (list<CCRect>::iterator it = _all_collision_rects.begin();it != _all_collision_rects.end();it ++)
		{
			CCRect& e_rect= (*it);
			if(e_rect.intersectsRect(player_rect)){
				return true;
			}
		}

		return false;
	}

	void Enemy::processCreateCmds(){
		list<CreateArg*>::iterator it = _all_create_cmd.begin();
		list<CreateArg*>::iterator itend = _all_create_cmd.end();

		for (;it != itend;)
		{
			CreateArg* cmd = *it;	
			_createEnemy(cmd);
	
			free(cmd);
			it = _all_create_cmd.erase(it);
		}
	}

	void Enemy::pushCreateCmd( CreateArg* arg )
	{
		_all_create_cmd.push_back(arg);
	}

	list<Enemy::CreateArg*> Enemy::_all_create_cmd;
	list<Enemy*> Enemy::_all_active_enemys;

	CCNode* Enemy::_all_enemy_parent = NULL;

}